#pragma once
#include "ProjectPlan/PPProjTree.h"
#include <list>

namespace LBPROJ
{
    class CProjectTreeNode : public IProjectTreeNode
    {
        IMPLEMENT_REFCOUNTING(CProjectTreeNode)
    public:
        CProjectTreeNode();
        virtual ~CProjectTreeNode();

    public:
        virtual const std::wstring& GetID() const;
        virtual void SetID(const std::wstring& id);

        virtual const std::wstring& GetName() const;
        virtual void SetName(const std::wstring&);

        virtual CRefPtr<IPPContext> GetContext() const;
        virtual void SetContext(const CRefPtr<IPPContext>& pContext);

        virtual CRefPtr<IProjectTreeNode> GetParent() const;
        virtual void SetParent(const CRefPtr<IProjectTreeNode>& pParent);

        virtual void AddItem(const CRefPtr<IProjectTreeNode>& pItem, const CRefPtr<IProjectTreeNode>& pPos = nullptr);
        virtual void DelItem(const CRefPtr<IProjectTreeNode>& pItem);
        virtual void DelAllItem();
        virtual CRefPtr<Iterator<IProjectTreeNode*>> CreateIterator(bool reversed = false) const;

        virtual bool Store(Data& data) const;

    protected:
    private:
        mutable std::wstring m_id;
        std::wstring m_name;
        CRefPtr<IPPContext> m_pContext;
        std::list<CRefPtr<IProjectTreeNode>> m_childList;
        CWeakPtr<IProjectTreeNode> m_pParent;

    };

    class CProjectTree : public IProjectTree
    {
        IMPLEMENT_REFCOUNTING(CProjectTree)
    public:
        CProjectTree();
        virtual ~CProjectTree();

    public:
        virtual CRefPtr<IProjectTreeNode> GetRoot() const;

        CRefPtr<IProjectTreeNode> FindNodeBySequence(int sequence) const;
        CRefPtr<IProjectTreeNode> FindNodeByID(const std::wstring& id) const;

        virtual bool Open(LBPROJSTREAM::IProjPlanStreamDatabase* pDb);
        virtual bool Write(LBPROJSTREAM::IProjPlanStreamDatabase* pDb) const;

    protected:
    private:
        CRefPtr<IProjectTreeNode> m_pRoot;
    };

}